#include <string.h>
#include <stdio.h>
#include <utime.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

static const char sign[]="Copyright (c) Network Associates Inc.\x1A\0Olympus\0\0\xCB";

// Encode-Decode McAfee VirusScan base files
#include "McEnc.cpp"

#define Memcmp(A,B) memcmp((A),(B),sizeof(B))
bool DecodeFile(char * name)
{
	struct stat statbuf;
	struct utimbuf ut;

//Open file
	int file=open(name,O_RDWR);
	if (file<0)
	{
	    perror(name);
	    return false;
	}

//Just get some info about the file
	if (fstat(file,&statbuf) < 0)
	{
	    perror(name);
	    close(file);
	    return false;
	}

//Prepare Memory-Mapping on the file
	unsigned char * fmap=(unsigned char*)mmap(0,statbuf.st_size,PROT_READ | PROT_WRITE, MAP_SHARED, file, 0);
	if (fmap == (unsigned char*) -1)
	{
	    perror(name);
	    close(file);
	    return false;
	}

//Let kernel knows - how to optimize page read-write on the file
	madvise(fmap,statbuf.st_size,MADV_SEQUENTIAL);

//We ready to check signature of the file
	if (Memcmp(fmap,sign))
	{
		fprintf(stderr,"%s: not a McAfee VirusBase file!\n",name);
		munmap(fmap,statbuf.st_size);
		close(file);
		return false;
	}

// Do Actual decryption-encryption
	MakeTable(*(unsigned short*)(fmap+0x32));
	DoDecode(fmap,0x34,statbuf.st_size);
// It's All!

//Just cleanup
	munmap(fmap,statbuf.st_size);
	close(file);

// Make mtime alone
	ut.actime=statbuf.st_atime;
	ut.modtime=statbuf.st_mtime;
	utime(name,&ut);
//	utime(name,(struct utimbuf*)&statbuf.st_atime);
	return true;
}

int main(int n, char ** s)
{
	int count=0;
	while (*++s) if (DecodeFile(*s)) count++;
	return count;
}
